﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Primitives;
using System.IO;
using System.Windows;
using System.Xml.Serialization;

using DSLPedItemWizard.ViewModels;
using DSLPedItemWizard.Views;

using Dsl.Ped.Framework.AddIns;
using Dsl.Ped.Framework.Common;

using GalaSoft.MvvmLight.Messaging;

namespace DSLPedItemWizard
{
    /// <summary>
    /// Interaction logic for MainWizardWindow.xaml
    /// </summary>
    public partial class MainWizardWindow
    {
        private MainWizardWindowViewModel model;

        public MainWizardWindow(ComposablePartCatalog catalog)
        {
            InitializeComponent();

            var messenger = new Messenger();
            model = new MainWizardWindowViewModel(new List<IWizardPage>() { new IntroWizardView(messenger), new SelectionWizardView(catalog, messenger) }, messenger);
            this.DataContext = model;
        }

        private void CancelButton_OnClick(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        private void FinishButton_OnClick(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            this.Close();
        }

        public string GetFileContent()
        {
            var addIn = model.SelectedAddIn;
            if (addIn == null)
            {
                return string.Empty;
            }

            var result = this.GetFileContent(model.SelectedAddIn);
            return result;
        }

        public string GetFileContent(Lazy<IDslPedAddIn, IDslPedAddInMetadata> addIn)
        {
            var defaultNamespace = addIn.Metadata.Namespace;
            var projectiveType = addIn.Metadata.ProjectiveType;

            // Don't know to which type do the serialization
            if (projectiveType == null)
            {
                return string.Empty;
            }

            var projectiveObject = addIn.Value.GetDefaultObject();

            // If the projective object taken from the interface is null, generate
            // default object from the projective type
            if (projectiveObject == null)
            {
                return this.GetDefaultFileContent(projectiveType, defaultNamespace);
            }

            // Try to serialize default projective object using the projective type.
            // If it fails, return default file content
            try
            {
                var serializer = new XmlSerializer(projectiveType, defaultNamespace ?? string.Empty);
                var writer = new StringWriter();
                serializer.Serialize(writer, projectiveObject);
                return writer.ToString();
            }
            catch (Exception)
            {
                return this.GetDefaultFileContent(projectiveType, defaultNamespace);
            }
        }

        /// <summary>
        /// Get type of object that can represent the file instance
        /// </summary>
        /// <returns>Type of object that can represent the file instance</returns>
        public Type GetFileType()
        {
            if (model.SelectedAddIn != null)
            {
                return model.SelectedAddIn.Metadata.ProjectiveType;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Get object representing the default file instance
        /// </summary>
        /// <returns>Object that represents the instance of a default file content</returns>
        public IProjective GetFileObject()
        {
            if (model.SelectedAddIn != null)
            {
                return model.SelectedAddIn.Value.GetDefaultObject();
            }
            else
            {
                return null;
            }
        }

        public string GetDefaultFileContent(Type projectiveType, string defaultNamespace)
        {
            try
            {
                var serializer = new XmlSerializer(projectiveType, defaultNamespace ?? string.Empty);
                var writer = new StringWriter();
                var projectiveObject = Activator.CreateInstance(projectiveType);
                serializer.Serialize(writer, projectiveObject);
                return writer.ToString();
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
    }
}
